Skip to main content
Glama

MCP Forge

MCP Server Generator for Smithery (mcp-forge).md19.7 kB
<img src="https://r2cdn.perplexity.ai/pplx-full-logo-primary-dark%402x.png" class="logo" width="120"/> # --- # MCP Server Generator for Smithery (mcp-forge) This document provides the complete setup for creating a powerful MCP server that generates other MCP servers for Smithery, with seamless integration into Cursor IDE. ## Project Structure ``` mcp-forge/ ├── src/ │ ├── index.js │ ├── templates/ │ │ ├── basic.js │ │ ├── web-search.js │ │ └── database.js ├── Dockerfile ├── smithery.yaml ├── package.json └── README.md ``` ## Implementation Files ### 1. package.json ```json { "name": "@your-username/mcp-forge", "version": "1.0.0", "description": "MCP server for generating other MCP servers in Smithery", "main": "src/index.js", "type": "module", "scripts": { "start": "node src/index.js" }, "keywords": ["mcp", "smithery", "generator", "cursor"], "author": "Your Name", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^0.1.0", "fs-extra": "^11.1.1", "lodash": "^4.17.21" } } ``` ### 2. src/index.js ```javascript import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import fs from 'fs-extra'; import path from 'path'; import { fileURLToPath } from 'url'; import { createBasicTemplate } from './templates/basic.js'; import { createWebSearchTemplate } from './templates/web-search.js'; import { createDatabaseTemplate } from './templates/database.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Create a new MCP server const server = new Server( { name: "mcp-forge", version: "1.0.0" }, { capabilities: { tools: { // Tool 1: Generate a new MCP server generate_mcp_server: { description: "Generates a new MCP server with the specified configuration", parameters: { type: "object", properties: { name: { type: "string", description: "Name of the MCP server" }, template: { type: "string", enum: ["basic", "web-search", "database"], description: "Template to use for the MCP server" }, outputDir: { type: "string", description: "Directory to output the generated MCP server" } }, required: ["name", "template", "outputDir"] }, handler: async (params) => { const { name, template, outputDir } = params; try { // Create output directory if it doesn't exist await fs.ensureDir(outputDir); let templateFn; switch (template) { case "basic": templateFn = createBasicTemplate; break; case "web-search": templateFn = createWebSearchTemplate; break; case "database": templateFn = createDatabaseTemplate; break; default: templateFn = createBasicTemplate; } const files = templateFn(name); // Write files for (const [filePath, content] of Object.entries(files)) { await fs.writeFile(path.join(outputDir, filePath), content); } return { success: true, message: `MCP server "${name}" has been generated in ${outputDir}`, files: Object.keys(files) }; } catch (error) { return { success: false, error: error.message }; } } }, // Tool 2: Get Cursor integration config get_cursor_integration: { description: "Generates the integration code for Cursor IDE", parameters: { type: "object", properties: { packageName: { type: "string", description: "NPM package name of the MCP server" }, config: { type: "object", description: "Configuration object for the MCP server" } }, required: ["packageName"] }, handler: async (params) => { const { packageName, config = {} } = params; const configString = JSON.stringify(config).replace(/"/g, '\\"'); const cursorConfig = { command: "npx", args: [ "-y", "@smithery/cli@latest", "run", packageName, "--config", `"${configString}"` ] }; const mcpJson = { mcpServers: { [packageName.split('/').pop()]: cursorConfig } }; return { mcpJson: JSON.stringify(mcpJson, null, 2), commandLine: `npx -y @smithery/cli@latest run ${packageName} --config "${configString}"`, instructions: "Add this to your ~/.cursor/mcp.json file to integrate with Cursor IDE" }; } }, // Tool 3: Deploy to Smithery deploy_to_smithery: { description: "Provides instructions for deploying the MCP server to Smithery", parameters: { type: "object", properties: { repoUrl: { type: "string", description: "GitHub repository URL of the MCP server" } }, required: ["repoUrl"] }, handler: async (params) => { const { repoUrl } = params; return { steps: [ "1. Push your code to GitHub repository: " + repoUrl, "2. Visit https://smithery.ai/dashboard", "3. Click 'Deploy New Server'", "4. Enter your repository URL", "5. Follow the deployment instructions" ], note: "Ensure your repository has a valid Dockerfile and smithery.yaml at the root" }; } } } } } ); // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); ``` ### 3. src/templates/basic.js ```javascript export function createBasicTemplate(name) { return { 'package.json': `{ "name": "@your-username/${name}", "version": "1.0.0", "description": "MCP server for ${name}", "main": "index.js", "type": "module", "scripts": { "start": "node index.js" }, "keywords": ["mcp", "smithery"], "author": "Your Name", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^0.1.0" } }`, 'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; // Create a new MCP server const server = new Server( { name: "${name}", version: "1.0.0" }, { capabilities: { tools: { example_tool: { description: "An example tool", parameters: { type: "object", properties: { input: { type: "string", description: "Input parameter" } }, required: ["input"] }, handler: async (params) => { return { result: \`Processed: \${params.input}\` }; } } } } } ); // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); `, 'Dockerfile': `FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "index.js"] `, 'smithery.yaml': `startCommand: type: stdio configSchema: type: object properties: exampleConfig: type: string description: Example configuration parameter required: [] commandFunction: | function generateCommand(config) { return { command: "node", args: ["index.js"], env: {} }; } ` }; } ``` ### 4. src/templates/web-search.js ```javascript export function createWebSearchTemplate(name) { return { 'package.json': `{ "name": "@your-username/${name}", "version": "1.0.0", "description": "Web search MCP server", "main": "index.js", "type": "module", "scripts": { "start": "node index.js" }, "keywords": ["mcp", "smithery", "web-search"], "author": "Your Name", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^0.1.0", "node-fetch": "^3.3.2" } }`, 'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import fetch from 'node-fetch'; // Create a new MCP server const server = new Server( { name: "${name}", version: "1.0.0" }, { capabilities: { tools: { web_search: { description: "Search the web", parameters: { type: "object", properties: { query: { type: "string", description: "Search query" }, limit: { type: "number", description: "Maximum number of results" } }, required: ["query"] }, handler: async (params) => { const { query, limit = 5 } = params; const apiKey = process.env.SEARCH_API_KEY; if (!apiKey) { return { error: "API key not provided. Set SEARCH_API_KEY environment variable." }; } try { // Implement your search API call here // This is a placeholder const response = await fetch(\`https://api.example.com/search?q=\${encodeURIComponent(query)}&limit=\${limit}\`, { headers: { 'Authorization': \`Bearer \${apiKey}\` } }); const data = await response.json(); return { results: data.results || [] }; } catch (error) { return { error: error.message }; } } } } } } ); // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); `, 'Dockerfile': `FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "index.js"] `, 'smithery.yaml': `startCommand: type: stdio configSchema: type: object properties: searchApiKey: type: string description: API key for the search service required: ["searchApiKey"] commandFunction: | function generateCommand(config) { return { command: "node", args: ["index.js"], env: { SEARCH_API_KEY: config.searchApiKey } }; } ` }; } ``` ### 5. src/templates/database.js ```javascript export function createDatabaseTemplate(name) { return { 'package.json': `{ "name": "@your-username/${name}", "version": "1.0.0", "description": "Database MCP server", "main": "index.js", "type": "module", "scripts": { "start": "node index.js" }, "keywords": ["mcp", "smithery", "database"], "author": "Your Name", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^0.1.0", "pg": "^8.11.0" } }`, 'index.js': `import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import pg from 'pg'; const { Pool } = pg; // Initialize database connection let pool; // Create a new MCP server const server = new Server( { name: "${name}", version: "1.0.0" }, { capabilities: { tools: { run_query: { description: "Run SQL query on database", parameters: { type: "object", properties: { query: { type: "string", description: "SQL query to execute" }, params: { type: "array", description: "Query parameters", items: { type: "string" } } }, required: ["query"] }, handler: async (params) => { const { query, params: queryParams = [] } = params; if (!pool) { const connectionString = process.env.DATABASE_URL; if (!connectionString) { return { error: "Database connection string not provided. Set DATABASE_URL environment variable." }; } pool = new Pool({ connectionString }); } try { const result = await pool.query(query, queryParams); return { rows: result.rows, rowCount: result.rowCount }; } catch (error) { return { error: error.message }; } } }, describe_table: { description: "Describe database table structure", parameters: { type: "object", properties: { tableName: { type: "string", description: "Name of the table to describe" } }, required: ["tableName"] }, handler: async (params) => { const { tableName } = params; if (!pool) { const connectionString = process.env.DATABASE_URL; if (!connectionString) { return { error: "Database connection string not provided. Set DATABASE_URL environment variable." }; } pool = new Pool({ connectionString }); } try { const query = \` SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_name = $1 ORDER BY ordinal_position \`; const result = await pool.query(query, [tableName]); return { columns: result.rows, count: result.rowCount }; } catch (error) { return { error: error.message }; } } } } } } ); // Start the server with stdio transport const transport = new StdioServerTransport(); await server.connect(transport); `, 'Dockerfile': `FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "index.js"] `, 'smithery.yaml': `startCommand: type: stdio configSchema: type: object properties: databaseUrl: type: string description: PostgreSQL connection string required: ["databaseUrl"] commandFunction: | function generateCommand(config) { return { command: "node", args: ["index.js"], env: { DATABASE_URL: config.databaseUrl } }; } ` }; } ``` ### 6. Dockerfile ```dockerfile FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm install COPY . . CMD ["node", "src/index.js"] ``` ### 7. smithery.yaml ```yaml startCommand: type: stdio configSchema: type: object properties: smitheryApiToken: type: string description: Smithery API token for deployment operations required: [] commandFunction: | function generateCommand(config) { return { command: "node", args: ["src/index.js"], env: { SMITHERY_API_TOKEN: config.smitheryApiToken || "" } }; } ``` ## Integration with Cursor IDE To integrate this MCP server with Cursor IDE, add the following configuration to your global mcp.json file: ```json { "mcpServers": { "mcp-forge": { "command": "npx", "args": [ "-y", "@smithery/cli@latest", "run", "@your-username/mcp-forge", "--config", "{}" ] } } } ``` ## Usage in Cursor Once integrated, you can use the following tools from Cursor: 1. `generate_mcp_server` - Generate a new MCP server from a template 2. `get_cursor_integration` - Get integration code for Cursor IDE 3. `deploy_to_smithery` - Get instructions for deploying to Smithery ## Deployment Steps 1. Create the project structure as outlined above 2. Implement the provided code files 3. Test locally using `npm start` 4. Push to GitHub 5. Deploy on Smithery: - Go to Smithery dashboard - Click "Deploy New Server" - Enter your GitHub repository URL - Follow deployment instructions 6. After deployment, integrate with Cursor using the provided configuration This MCP server enables rapid development of other MCP servers by providing templates, configuration assistance, and deployment guidance, all within the Cursor IDE environment. <div style="text-align: center">⁂</div> [^1]: https://pplx-res.cloudinary.com/image/upload/v1742942047/user_uploads/ZyqsNIkkkuKueqU/image.jpg [^2]: https://pplx-res.cloudinary.com/image/upload/v1742942066/user_uploads/RpFOwYlSkfbzvbh/image.jpg [^3]: https://ppl-ai-file-upload.s3.amazonaws.com/web/direct-files/17146172/bca66741-9637-4a7f-b0b7-3e88bf3e9130/mcp.rules.md [^4]: https://pplx-res.cloudinary.com/image/upload/v1742944001/user_uploads/uThfdtgctaUXHgK/image.jpg [^5]: https://cursor101.com/article/cursor-what-is-mcp [^6]: https://www.youtube.com/watch?v=RCFe1L9qm3E [^7]: https://www.youtube.com/watch?v=8m-O_KiHRjk [^8]: https://mcp.so/server/unreal-mcp-server/AlexKissiJr [^9]: https://github.com/daniel-lxs/mcp-server-starter [^10]: https://smithery.ai/docs/config [^11]: https://www.reddit.com/r/cursor/comments/1jbdrof/how_to_install_mcp_tools_in_cursor_ide/ [^12]: https://glama.ai/mcp/servers/tg4ugmp8jr [^13]: https://smithery.ai/new [^14]: https://github.com/kirill-markin/example-mcp-server [^15]: https://glama.ai/mcp/servers/rbgsskqcgb/blob/main/smithery.yaml [^16]: https://docs.cursor.com/context/model-context-protocol [^17]: https://jigsawstack.com/blog/jigsawstack-mcp-servers [^18]: https://www.apideck.com/blog/unlocking-ai-potential-how-to-quickly-set-up-a-cursor-mcp-server [^19]: https://www.youtube.com/watch?v=WPdaWUnm2ik [^20]: https://glama.ai/mcp/servers/@chrisboden/mcp_template [^21]: https://forum.cursor.com/t/how-to-use-mcp-server/50064 [^22]: https://smithery.ai [^23]: https://smithery.ai/server/@nicknochnack/BuildMCPServer [^24]: https://www.youtube.com/watch?v=2GHRDoFquOo

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chromewillow/mcp-forge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server